using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace sprocgen.Entities
{
    public class GenConfig
    {
        public string Namespace;
        public string ClassName;
        public string ConnectionStringKey;
        public readonly ConnectionConfig DatabaseConnection = new ConnectionConfig();
        public readonly List<StoredProcedureConfig> StoredProcedures = new List<StoredProcedureConfig>();

        public static XmlQualifiedName CreateGenConfigSchema(XmlSchemaSet schemaSet)
        {
            XmlQualifiedName name = new XmlQualifiedName("config");
            return name;
        }

        public void ReadXml(XmlDocument doc)
        {
            XmlNode root = doc.DocumentElement;
            string configVersion = root.SelectSingleNode("configversion").InnerText;
            Namespace = root.SelectSingleNode("namespace").InnerText;
            ClassName = root.SelectSingleNode("classname").InnerText;
            ConnectionStringKey = root.SelectSingleNode("connectionstringkey").InnerText;

            XmlNode dbconnNode = root.SelectSingleNode("databaseconnection");
            DatabaseConnection.Server = dbconnNode.SelectSingleNode("server").InnerText;
            DatabaseConnection.Database = dbconnNode.SelectSingleNode("database").InnerText;
            DatabaseConnection.IsTrustedConnection = bool.Parse(dbconnNode.SelectSingleNode("trustedconnection").InnerText);
            DatabaseConnection.UserName = dbconnNode.SelectSingleNode("username").InnerText;
            DatabaseConnection.Password = dbconnNode.SelectSingleNode("password").InnerText;

            StoredProcedures.Clear();

            XmlNode sprocsNode = root.SelectSingleNode("storedprocedures");
            XmlNodeList sprocs = sprocsNode.SelectNodes("storedprocedure");
            foreach (XmlNode sprocNode in sprocs)
            {
                StoredProcedureConfig sproc = new StoredProcedureConfig();
                StoredProcedures.Add(sproc);

                sproc.ID = int.Parse(sprocNode.SelectSingleNode("id").InnerText);
                sproc.Schema = sprocNode.SelectSingleNode("schema").InnerText;
                sproc.Name = sprocNode.SelectSingleNode("name").InnerText;
                sproc.Generate = bool.Parse(sprocNode.SelectSingleNode("generate").InnerText);

                XmlNode paramsNode = sprocNode.SelectSingleNode("parameters");
                XmlNodeList paramNodes = paramsNode.SelectNodes("parameter");
                foreach (XmlNode paramNode in paramNodes)
                {
                    ParameterConfig param = new ParameterConfig();
                    sproc.Parameters.Add(param);

                    param.ID = int.Parse(paramNode.SelectSingleNode("id").InnerText);
                    param.Name = paramNode.SelectSingleNode("name").InnerText;
                    param.DataType = paramNode.SelectSingleNode("datatype").InnerText;
                    string strLength = paramNode.SelectSingleNode("length").InnerText;
                    if (string.IsNullOrEmpty(strLength))
                        param.Length = null;
                    else
                        param.Length = int.Parse(strLength);
                    param.HasDefaultValue = bool.Parse(paramNode.SelectSingleNode("hasdefaultvalue").InnerText);
                    param.IsOutParameter = bool.Parse(paramNode.SelectSingleNode("isoutparameter").InnerText);
                }
            }
        }

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteStartDocument();
            writer.WriteStartElement("config");

            writer.WriteStartElement("configversion");
            writer.WriteString("1.0");
            writer.WriteEndElement();

            writer.WriteStartElement("namespace");
            writer.WriteString(Namespace);
            writer.WriteEndElement();

            writer.WriteStartElement("classname");
            writer.WriteString(ClassName);
            writer.WriteEndElement();

            writer.WriteStartElement("connectionstringkey");
            writer.WriteString(ConnectionStringKey);
            writer.WriteEndElement();

            // <databaseconnection>

            writer.WriteStartElement("databaseconnection");

            writer.WriteStartElement("server");
            writer.WriteString(DatabaseConnection.Server);
            writer.WriteEndElement();

            writer.WriteStartElement("database");
            writer.WriteString(DatabaseConnection.Database);
            writer.WriteEndElement();

            writer.WriteStartElement("trustedconnection");
            writer.WriteValue(DatabaseConnection.IsTrustedConnection);
            writer.WriteEndElement();

            writer.WriteStartElement("username");
            writer.WriteString(DatabaseConnection.UserName);
            writer.WriteEndElement();

            writer.WriteStartElement("password");
            writer.WriteString(DatabaseConnection.Password);
            writer.WriteEndElement();
            
            writer.WriteEndElement(); // end databsaeconnection

            // stored procedures
            writer.WriteStartElement("storedprocedures");

            foreach (StoredProcedureConfig storedProc in StoredProcedures)
            {
                writer.WriteStartElement("storedprocedure");

                writer.WriteStartElement("id");
                writer.WriteValue(storedProc.ID);
                writer.WriteEndElement();

                writer.WriteStartElement("schema");
                writer.WriteValue(storedProc.Schema);
                writer.WriteEndElement();

                writer.WriteStartElement("name");
                writer.WriteValue(storedProc.Name);
                writer.WriteEndElement();

                writer.WriteStartElement("generate");
                writer.WriteValue(storedProc.Generate);
                writer.WriteEndElement();

                writer.WriteStartElement("parameters");
                foreach (ParameterConfig param in storedProc.Parameters)
                {
                    writer.WriteStartElement("parameter");

                    writer.WriteStartElement("id");
                    writer.WriteValue(param.ID);
                    writer.WriteEndElement();

                    writer.WriteStartElement("name");
                    writer.WriteValue(param.Name);
                    writer.WriteEndElement();

                    writer.WriteStartElement("datatype");
                    writer.WriteValue(param.DataType);
                    writer.WriteEndElement();

                    writer.WriteStartElement("length");
                    writer.WriteValue(param.Length);
                    writer.WriteEndElement();

                    writer.WriteStartElement("hasdefaultvalue");
                    writer.WriteValue(param.HasDefaultValue);
                    writer.WriteEndElement();

                    writer.WriteStartElement("isoutparameter");
                    writer.WriteValue(param.IsOutParameter);
                    writer.WriteEndElement();

                    writer.WriteEndElement(); // end parameter
                }
                writer.WriteEndElement(); // end parameters

                writer.WriteEndElement(); // end storedprocedure
            }

            writer.WriteEndElement(); // end storedprocedures

            writer.WriteEndElement(); // end config
            writer.WriteEndDocument();
        }
    }
}
